package com.tyut.musicdreamer.service.gateway.filter;

import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpCookie;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * Sa-Token用户ID过滤器
 * 从Sa-Token上下文中获取用户ID，并添加到请求头
 * 使用响应式API，确保在Spring Cloud Gateway环境中正常工作
 */
@Component
@Slf4j
public class SaTokenUserIdFilter implements GlobalFilter, Ordered {

    /**
     * 用户ID请求头名称
     */
    public static final String USER_ID_HEADER = "X-User-Id";
    
    /**
     * Sa-Token cookie名称
     */
    private static final String SA_TOKEN_COOKIE = "satoken";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 记录原始请求
        ServerHttpRequest request = exchange.getRequest();
        log.debug("SaTokenUserIdFilter处理请求: {}, 路径: {}", request.getMethod(), request.getPath());
        
        // 检查是否已经有用户ID请求头
        if (request.getHeaders().containsKey(USER_ID_HEADER)) {
            log.debug("请求头中已有用户ID: {}", request.getHeaders().getFirst(USER_ID_HEADER));
            return chain.filter(exchange);
        }
        
        // 获取token值
        String tokenValue = getTokenValue(request);
        
        // 如果没有token，直接继续过滤器链
        if (!StringUtils.hasText(tokenValue)) {
            log.debug("未找到token");
            return chain.filter(exchange);
        }
        
        log.debug("获取到token值: {}", tokenValue);
        
        try {
            // 使用token获取用户ID
            Object loginId = StpUtil.getLoginIdByToken(tokenValue);
            
            if (loginId != null) {
                log.debug("根据token获取到用户ID: {}", loginId);
                
                // 创建新的请求，添加用户ID头
                ServerHttpRequest newRequest = request.mutate()
                        .header(USER_ID_HEADER, loginId.toString())
                        .build();
                
                // 使用新的请求创建新的exchange
                ServerWebExchange newExchange = exchange.mutate()
                        .request(newRequest)
                        .build();
                
                log.debug("已添加用户ID到请求头: {}", loginId);
                
                // 继续过滤器链，使用更新后的exchange
                return chain.filter(newExchange);
            }
        } catch (Exception e) {
            log.warn("根据token获取用户ID时发生异常: {}", e.getMessage());
        }
        
        // 如果未找到用户ID或发生异常，继续使用原始exchange
        return chain.filter(exchange);
    }
    
    /**
     * 从请求中获取token值
     */
    private String getTokenValue(ServerHttpRequest request) {
        // 1. 从cookie中获取
        HttpCookie saTokenCookie = request.getCookies().getFirst(SA_TOKEN_COOKIE);
        if (saTokenCookie != null && StringUtils.hasText(saTokenCookie.getValue())) {
            return saTokenCookie.getValue();
        }
        
        // 2. 从请求头中获取
        String tokenValue = request.getHeaders().getFirst(SA_TOKEN_COOKIE);
        if (StringUtils.hasText(tokenValue)) {
            return tokenValue;
        }
        
        // 3. 从请求参数中获取
        String paramToken = request.getQueryParams().getFirst(SA_TOKEN_COOKIE);
        if (StringUtils.hasText(paramToken)) {
            return paramToken;
        }
        
        return null;
    }

    @Override
    public int getOrder() {
        // 在Sa-Token认证过滤器之后执行，但在UserIdPropagationFilter之前
        return -95;
    }
} 